package com.lmf.zookeeper;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.List;

/**
 * 测试通过客户端API，连接zookeeper
 * @Test:
 * 目的是为了测试此方法，因为我们之前的代码的执行都要放在main方法中执行。
 * 我们通过@Test注解，我们就能使相应的方法不放在main方法中就可以直接运行，
 * 起到代码的测试作用
 *
 * @Before：
 * 此注解的目的是为了将@Befoe 作为首先执行的代码。用于资源的申请
 *
 * @After：
 * 此注解的目的是为了让每次释放资源之后都会执行此注解下的代码，
 * 即使程序出现了异常，依然还会执行这个。用于资源的释放
 */
public class zkClient {
    //注意：逗号前后不能有空格
    //连接的 “主机IP+端口号”，多台服务器之间使用逗号隔开
    private String connectString = "192.168.120.128:2181,192.168.120.130:2181,192.168.120.131:2181";
    //设置超时时长
    private int sessionTimeout = 200000;
    private ZooKeeper zooKeeper;

    //创建一个zookeeper对象,初始化的时候只是创建一个监听器，并不会触发这个监听器
    @Before
//    @Test
    public void init() throws IOException {
        zooKeeper = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            //重写一个监听器内容，也是初始化的监听器，并不会一开始就执行
            @Override
            public void process(WatchedEvent watchedEvent) {
                System.out.println("-----------------------------------------");
                try {
                    List<String> children = zooKeeper.getChildren("/", true);
                    for (String child : children) {
                        System.out.println(child);
                    }
//                    System.out.println("-----------------------------------------");

                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (KeeperException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    //在zookeeper中创建一个节点
    @Test
    public void create() throws InterruptedException, KeeperException, IOException {
        //this.init();
        String node = zooKeeper.create("/lmf/lmf2", "张三".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        System.out.println(node);
    }

    /**
     * 获取子节点并监听节点变化,注册一次监听一次，若要一直监视某个节点状态，需要在监视的过程中不断注册监听器
     * 获取子节点第一个是路径，第二个是监听函数，如果使用true，则会使用初始化函数中重写的监听函数
     * @throws InterruptedException
     * @throws KeeperException
     */
    @Test
    public void getChildren() throws InterruptedException, KeeperException {
        List<String> children = zooKeeper.getChildren("/servers", true);
        for (String child : children) {
            System.out.println(child);
        }
        //延时
        Thread.sleep(Long.MAX_VALUE);
    }

    //判断某个节点是否存在
    @Test
    public void exist() throws InterruptedException, KeeperException {
        Stat stat = zooKeeper.exists("/lmf", false);
        System.out.println(stat == null ? "not exist" : "exist");
    }
}
